/*
  KeePass Password Safe - The Open-Source Password Manager
  Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

using System;
using System.Collections.Generic;
using System.Text;

using KeePassLib.Serialization;

namespace KeePassLib.Keys
{
  public sealed class KeyProviderQueryContext
  {
    private IOConnectionInfo m_ioInfo;
    public IOConnectionInfo DatabaseIOInfo
    {
      get { return m_ioInfo; }
    }

    public string DatabasePath
    {
      get { return m_ioInfo.Path; }
    }

    private bool m_bCreatingNewKey;
    public bool CreatingNewKey
    {
      get { return m_bCreatingNewKey; }
    }

    private bool m_bSecDesktop;
    public bool IsOnSecureDesktop
    {
      get { return m_bSecDesktop; }
    }

    public KeyProviderQueryContext(IOConnectionInfo ioInfo, bool bCreatingNewKey,
        bool bOnSecDesktop)
    {
      if (ioInfo == null) throw new ArgumentNullException("ioInfo");

      m_ioInfo = ioInfo.CloneDeep();
      m_bCreatingNewKey = bCreatingNewKey;
      m_bSecDesktop = bOnSecDesktop;
    }
  }

  public abstract class KeyProvider
  {
    /// <summary>
    /// Name of your key provider (should be unique).
    /// </summary>
    public abstract string Name
    {
      get;
    }

    /// <summary>
    /// Property indicating whether the provider is exclusive.
    /// If the provider is exclusive, KeePass doesn't allow other
    /// key sources (master password, Windows user account, ...)
    /// to be combined with the provider.
    /// Key providers typically should return <c>false</c>
    /// (to allow non-exclusive use), i.e. don't override this
    /// property.
    /// </summary>
    public virtual bool Exclusive
    {
      get { return false; }
    }

    /// <summary>
    /// Property that specifies whether the returned key data
    /// gets hashed by KeePass first or is written directly to
    /// the user key data stream.
    /// Standard key provider plugins should return <c>false</c>
    /// (i.e. don't overwrite this property). Returning <c>true</c>
    /// may cause severe security problems and is highly
    /// discouraged.
    /// </summary>
    public virtual bool DirectKey
    {
      get { return false; }
    }

    // public virtual PwIcon ImageIndex
    // {
    //	get { return PwIcon.UserKey; }
    // }

    /// <summary>
    /// This property specifies whether the <c>GetKey</c> method might
    /// show a form or dialog. If there is any chance that the method shows
    /// one, this property must return <c>true</c>. Only if it's guaranteed
    /// that the <c>GetKey</c> method doesn't show any form or dialog, this
    /// property should return <c>false</c>.
    /// </summary>
    public virtual bool GetKeyMightShowGui
    {
      get { return true; }
    }

    /// <summary>
    /// This property specifies whether the key provider is compatible
    /// with the secure desktop mode. This almost never is the case,
    /// so you usually won't override this property.
    /// </summary>
    public virtual bool SecureDesktopCompatible
    {
      get { return false; }
    }

    public abstract byte[] GetKey(KeyProviderQueryContext ctx);
  }

#if DEBUG
  public sealed class SampleKeyProvider : KeyProvider
  {
    public override string Name
    {
      get { return "Built-In Sample Key Provider"; }
    }

    // Do not just copy this to your own key provider class! See above.
    public override bool GetKeyMightShowGui
    {
      get { return false; }
    }

    public override byte[] GetKey(KeyProviderQueryContext ctx)
    {
      return new byte[] { 2, 3, 5, 7, 11, 13 };
    }
  }
#endif
}
